using NUnit.Framework;
using Nuwanda.TfsSpotlight.Shell.Proxies;
using Nuwanda.TfsSpotlight.Shell.Proxies.Interfaces;
using Nuwanda.TfsSpotlight.Shell.Services.Interfaces;
using Rhino.Mocks;

namespace Nuwanda.TfsSpotlight.Shell.Tests.Proxies
{
    [TestFixture]
    public class TabStripPresenterTests
    {
        private MockRepository _mocks;
        private ITabStrip _tabStripMock;
        private ITabsService _tabsServiceMock;
        private IMenuService _menuServiceMock;

        private ITabStripPresenter _testSubject;

        [SetUp]
        public void SetUp()
        {
            this._mocks = new MockRepository();
            this._tabStripMock = this._mocks.StrictMock<ITabStrip>();
            this._tabsServiceMock = this._mocks.StrictMock<ITabsService>();
            this._menuServiceMock = this._mocks.StrictMock<IMenuService>();

            this._testSubject = new TabStripPresenter(
                this._tabStripMock, this._tabsServiceMock, this._menuServiceMock);
        }

        [Test]
        public void WhenAskedTo_Initialize_Should_AttachToView()
        {
            using (this._mocks.Record())
            {
                this._tabStripMock.AttachPresenter(this._testSubject);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.Initialize();
            }
        }

        [Test]
        public void WhenAskedTo_HandleClosingTab_Should_ShouldRemoveTabViaTabsService_And_InvalidateCommands()
        {
            var tab = this._mocks.StrictMock<ITabStripItem>();
            var tabPresenter = this._mocks.StrictMock<ITabPresenter>();

            using (this._mocks.Record())
            {
                Expect.Call(tab.Presenter).Return(tabPresenter);
                this._tabsServiceMock.HandleTabRemoved(tabPresenter);
                this._menuServiceMock.InvalidateCommands(this._testSubject);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.HandleTabClosing(tab);
            }
        }

        [Test]
        public void WhenAskedTo_HandleSelectedTab_Should_ShouldSelectTabViaTabsService_And_InvalidateCommands()
        {
            var tab = this._mocks.StrictMock<ITabStripItem>();
            var tabPresenter = this._mocks.StrictMock<ITabPresenter>();

            using (this._mocks.Record())
            {
                Expect.Call(tab.Presenter).Return(tabPresenter);
                this._tabsServiceMock.HandleSelectedTabHanged(tabPresenter);
                this._menuServiceMock.InvalidateCommands(this._testSubject);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.HandleSelectedTabChanged(tab);
            }
        }

        #region Scroll scenarios

        [Test]
        public void WhenAskedTo_HandleScrollForward_And_CurrentlySelectedTabIsInTheMiddle_Should_SelectNextTab()
        {
            using (this._mocks.Record())
            {
                Expect.Call(this._tabStripMock.SelectedTabIndex).Return(2);
                Expect.Call(this._tabStripMock.Count).Return(4);
                this._tabStripMock.SelectTab(3);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.HandleTabScrolled(1);
            }
        }

        [Test]
        public void WhenAskedTo_HandleScrollBackward_And_CurrentlySelectedTabIsInTheMiddle_Should_SelectPrevTab()
        {
            using (this._mocks.Record())
            {
                Expect.Call(this._tabStripMock.SelectedTabIndex).Return(2);
                Expect.Call(this._tabStripMock.Count).Return(4);
                this._tabStripMock.SelectTab(1);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.HandleTabScrolled(-1);
            }
        }

        [Test]
        public void WhenAskedTo_HandleScrollForward_And_CurrentlySelectedTabIsLast_Should_SelectFirstTab()
        {
            using (this._mocks.Record())
            {
                Expect.Call(this._tabStripMock.SelectedTabIndex).Return(3);
                Expect.Call(this._tabStripMock.Count).Return(4);
                this._tabStripMock.SelectTab(0);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.HandleTabScrolled(1);
            }
        }

        [Test]
        public void WhenAskedTo_HandleScrollBackward_And_CurrentlySelectedTabIsLast_Should_SelectPrevTab()
        {
            using (this._mocks.Record())
            {
                Expect.Call(this._tabStripMock.SelectedTabIndex).Return(3);
                Expect.Call(this._tabStripMock.Count).Return(4);
                this._tabStripMock.SelectTab(2);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.HandleTabScrolled(-1);
            }
        }

        [Test]
        public void WhenAskedTo_HandleScrollForward_And_CurrentlySelectedTabIsFirst_Should_SelectNextTab()
        {
            using (this._mocks.Record())
            {
                Expect.Call(this._tabStripMock.SelectedTabIndex).Return(0);
                Expect.Call(this._tabStripMock.Count).Return(4);
                this._tabStripMock.SelectTab(1);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.HandleTabScrolled(1);
            }
        }

        [Test]
        public void WhenAskedTo_HandleScrollBackward_And_CurrentlySelectedTabIsFirst_Should_SelectLastTab()
        {
            using (this._mocks.Record())
            {
                Expect.Call(this._tabStripMock.SelectedTabIndex).Return(0);
                Expect.Call(this._tabStripMock.Count).Return(4);
                this._tabStripMock.SelectTab(3);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.HandleTabScrolled(-1);
            }
        }
        #endregion
    }
}